package com.hospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hospital.entity.*;
import com.hospital.enumeration.BedStatus;
import com.hospital.mapper.*;
import com.hospital.service.DepartmentService;
import com.hospital.vo.DepartmentIncomeVO;
import com.hospital.vo.DepartmentStatsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DepartmentServiceImpl implements DepartmentService {
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private HospitalizationRecordMapper hospitalizationRecordMapper;
    @Autowired
    private WardMapper wardMapper;
    @Autowired
    private BedMapper bedMapper;
    @Autowired
    private BillMapper billMapper;

    @Override
    public List<Department> getAllDepartments() {
        return departmentMapper.selectList(null);
    }

    @Override
    public List<DepartmentStatsVO> getDepartmentStats() {
        // 生成六个科室的统计数据
        List<DepartmentStatsVO> departmentStatsVOList = new ArrayList<>();

        List<Department> departments = departmentMapper.selectList(null);
        for (Department department : departments) {
            DepartmentStatsVO departmentStatsVO = new DepartmentStatsVO();
            // 科室名称
            departmentStatsVO.setDeptName(department.getDeptName());

            List<Long> wardIds = wardMapper.selectList(
                    new LambdaQueryWrapper<Ward>()
                            .eq(Ward::getDeptId, department.getDeptId())
            ).stream().map(Ward::getWardId).collect(Collectors.toList());

            List<Long> bedIds = bedMapper.selectList(
                    new LambdaQueryWrapper<Bed>()
                            .in(Bed::getWardId, wardIds)
            ).stream().map(Bed::getBedId).collect(Collectors.toList());
            // 科室总病床数
            departmentStatsVO.setTotalBeds(bedIds.size());

            // 科室当前病人数
            departmentStatsVO.setCurrentPatients(Math.toIntExact(bedMapper.selectCount(
                    new LambdaQueryWrapper<Bed>()
                            .in(Bed::getBedId, bedIds)
                            .eq(Bed::getStatus, BedStatus.OCCUPIED)
            )));

            // 获取当前时间的零点和第二天的零点
            LocalDateTime todayMidnight = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
            LocalDateTime tomorrowMidnight = todayMidnight.plusDays(1);

            // 科室今天入院人数
            departmentStatsVO.setTodayAdmission(Math.toIntExact(hospitalizationRecordMapper.selectCount(
                    new LambdaQueryWrapper<HospitalizationRecord>()
                            .isNull(HospitalizationRecord::getDischargeTime)
                            .in(HospitalizationRecord::getWardId, wardIds)
                            .ge(HospitalizationRecord::getAdmissionTime, todayMidnight)
                            .le(HospitalizationRecord::getAdmissionTime, tomorrowMidnight)
            )));

            // 科室今天出院人数
            departmentStatsVO.setTodayDischarge(Math.toIntExact(hospitalizationRecordMapper.selectCount(
                    new LambdaQueryWrapper<HospitalizationRecord>()
                            .isNotNull(HospitalizationRecord::getDischargeTime)
                            .in(HospitalizationRecord::getWardId, wardIds)
                            .ge(HospitalizationRecord::getDischargeTime, todayMidnight)
                            .le(HospitalizationRecord::getDischargeTime, tomorrowMidnight)
            )));

            departmentStatsVOList.add(departmentStatsVO);
        }

        return departmentStatsVOList;
    }

    @Override
    public List<DepartmentIncomeVO> getDepartmentIncome() {
        // 生成六个科室的收入数据
        List<DepartmentIncomeVO> departmentIncomeVOList = new ArrayList<>();

        List<Department> departments = departmentMapper.selectList(null);
        for (Department department : departments) {
            DepartmentIncomeVO departmentIncomeVO = DepartmentIncomeVO.builder()
                    .deptName(department.getDeptName())
                    .income(BigDecimal.ZERO)
                    .build();

            List<Long> wardIds = wardMapper.selectList(
                    new LambdaQueryWrapper<Ward>()
                            .eq(Ward::getDeptId, department.getDeptId())
            ).stream().map(Ward::getWardId).collect(Collectors.toList());

            billMapper.selectList(
                    new LambdaQueryWrapper<Bill>()
                            .in(Bill::getWardId, wardIds)
            ).forEach(bill -> {
                departmentIncomeVO.setIncome(departmentIncomeVO.getIncome()
                        .add(bill.getHospitalizationFee() != null ? bill.getHospitalizationFee() : BigDecimal.ZERO)
                        .add(bill.getTreatmentFee() != null ? bill.getTreatmentFee() : BigDecimal.ZERO));

            });

            departmentIncomeVOList.add(departmentIncomeVO);
        }
        return departmentIncomeVOList;
    }
}
